package com.zf.fastexcel.utils;

import com.zf.fastexcel.entity.TemplateFieldTest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 两个对象的属性属性差异对比
 */
@Slf4j
public class ObjectDiffCompareUtils {

    private static final Set<Class<?>> BASE_CLASS_SET = new HashSet<>(Arrays.asList(
            Byte.class, byte.class, Short.class, short.class, Integer.class, int.class,
            Long.class, long.class, Float.class, float.class, Double.class, double.class,
            Character.class, char.class, String.class
    ));

    /**
     * 对比两个对象的属性值的差异，只对比简单属性：Byte/Short/Integer/Long/Float/Double/Char/String，
     *
     * @param currentObject 当前对象
     * @param referObject   参考对象
     * @return 属性名 ->  referObject 中不同于 currentObject 中的属性值
     */
    public static <T> Map<String, String> compareBaseFieldDiff(T currentObject, T referObject) {
        // 对比结果
        HashMap<String, String> res = new HashMap<>();
        if (Objects.isNull(currentObject) || Objects.isNull(referObject)) {
            return res;
        }

        // 获取所有属性
        Field[] fieldList = currentObject.getClass().getDeclaredFields();
        if (ArrayUtils.isEmpty(fieldList)) {
            return res;
        }
        // 只取基本属性
        fieldList = Arrays.stream(fieldList)
                .filter(field -> {
                    // 设置可访问
                    field.setAccessible(true);
                    Class<?> type = field.getType();
                    // 如果不是基本类型和字符串，则忽略
                    return BASE_CLASS_SET.contains(type);
                }).toArray(Field[]::new);

        try {
            for (Field field : fieldList) {
                Object curValue = field.get(currentObject);
                Object referValue = field.get(referObject);
                // 如果值相等，则不做任何处理
                if (Objects.equals(curValue, referValue)) {
                    continue;
                }
                // 有差异，则将参考对象的属性值写入差异结果
                String diffValue = Objects.isNull(referValue) ? "" : String.valueOf(referValue);
                res.put(field.getName(), diffValue);
            }
        } catch (IllegalAccessException e) {
            log.error("对比发生错误：", e);
        }
        return res;
    }

    public static void main(String[] args) {
        TemplateFieldTest obj1 = new TemplateFieldTest();
        obj1.setName("张三");
        obj1.setTest("测试1");
        obj1.setAge(12);
        obj1.setTitle("标题1");
        TemplateFieldTest obj2 = new TemplateFieldTest();
        obj2.setName("李四");
        obj2.setTest("测试2");
        obj2.setAge(13);
        obj2.setTitle("标题2");
        Map<String, String> map = compareBaseFieldDiff(obj1, obj2);
        System.out.println(map);
    }
}
